﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace XFFSM
{

    public class DefualtExecuteState : IExecuteState
    {

        /// <summary>
        /// 保存所有的状态
        /// </summary>
        private Dictionary<string, IFSMState> states = new Dictionary<string, IFSMState>();

        public void OnEnter(FSMStateNode node)
        {
            IFSMState state = GetState(node.data.StateName);
            if (state != null) {
                state.OnEnter(node.controller);
            }
        }

        public void OnExit(FSMStateNode node)
        {
            IFSMState state = GetState(node.data.StateName);
            if (state != null)
            {
                state.OnExit(node.controller);
            }
        }

        public void OnFixedUpdate(FSMStateNode node)
        {
            IFSMState state = GetState(node.data.StateName);
            if (state != null)
            {
                state.OnFixedUpdate(node.controller);
            }
        }

        public void OnLateUpdate(FSMStateNode node)
        {
            IFSMState state = GetState(node.data.StateName);
            if (state != null)
            {
                state.OnLateUpdate(node.controller);
            }
        }

        public void OnUpdate(FSMStateNode node)
        {
            IFSMState state = GetState(node.data.StateName);
            if (state != null)
            {
                state.OnUpdate(node.controller);
            }
        }

        public IFSMState GetState(string stateName) {

            if (string.IsNullOrEmpty(stateName)) { return null; }

            IFSMState state = null;
            if ( !states.TryGetValue(stateName,out state) ) {
                // 需要创建
                Type type = GetType(stateName);
                if (type != null)
                {
                    state = Activator.CreateInstance(type) as IFSMState;
                }
                states.Add(stateName, state);
            }


            return state;
        }

        public Type GetType(string name)
        {

            if (string.IsNullOrEmpty(name)) return null; 

            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            foreach (var item in assemblies)
            {

                if (item.FullName.StartsWith("UnityEngine") || item.FullName.StartsWith("UnityEditor")
                    || item.FullName.StartsWith("System") || item.FullName.StartsWith("Microsoft"))
                { continue; }

                //Debug.Log(item.FullName);

                Type t = item.GetTypes().Where(x => x.FullName.Equals(name)).FirstOrDefault();

                if (t != null && t.GetInterfaces().Where(x => x == typeof(IFSMState)).FirstOrDefault() != null)
                {
                    return t;
                }
            }
            return null;
        }

    }
}

